package com.game.battleship.data.transformer;

import com.game.battleship.data.Direction;
import com.game.battleship.data.Game;
import com.game.battleship.data.Ship;
import com.game.battleship.data.ShipCellsHolder;


/**
 * Class that supports transformations between Ship's fields representations
 * @author vasil.konstantinov
 * @editor vtkhanh
 *
 */
public class ShipRepresentationTransformer {
	
	/**
	 * 
	 * @param ship
	 * @return different representation of the ship's fields - the method name says enough
	 */
	public static ShipCellsHolder getShipCellsHolderFromShip(Ship ship){
		int length = ship.getLength();
		
		int[] cells = ship.getBoardCells();
		int firstCell = getMinCell(cells);
		
		Direction d = getShipDirection(cells[0], cells[1]);
		
		ShipCellsHolder result = new ShipCellsHolder(length,firstCell,d);
		return result;
	}
	
	private static int getMinCell(int[] cells){		
		int min = Integer.MAX_VALUE;
		for (int i = 0 ; i < cells.length ; i++) {
			if (min > cells[i]) {
				min = cells[i];
			}
		}
		return min;
	}
	
	private static Direction getShipDirection(int cell1, int cell2){
		short boardSide = Game.BOARD_SIDE;
		if( (cell1-cell2) % boardSide == 0){
			return Direction.VERTICAL;
		} else if( (cell1 - cell2) / boardSide == 0){
			return Direction.HORIZONTAL;
		} else{
			//TODO : impossible case - handle exception
			return null;
		}
	}
	
	
	/**
	 * @param holder
	 * @return different representation of the ship's fields - the method name says enough
	 */
	public static Ship getShipFromShipCellsHolder(ShipCellsHolder holder){
		int length = holder.getLength();
		int[] cells = new int[length];
		short factor = 1;
		short firstCell = (short) holder.getFirstCell();
		Direction direction = holder.getDirection();
		
		switch (direction) {
		case HORIZONTAL:
			factor = 1;
			break;
		case VERTICAL:
			factor = Game.BOARD_SIDE;
			break;
		default:
			break;
		}
		
		for(int i = 0 ; i < length ; i++){
			cells[i] = (short) (firstCell + i*factor);
		}
		Ship result = new Ship((short)length,cells) ;
		
		return result;
	}	
}
